<template>
  <!-- modal=false时给对话框添加no-modal样式,给drag提供判断依据,判断是否模态对话框 -->
  <div
    ref="dialog"
    v-drag-dialog:[draggable]="{handler: onDrag}"
    :class="modal?'dialog-mask':'dialog-mask no-modal'"
    :style="style1"
  >
    <!-- FIX iframe会吞掉mouse事件,修复方法:pointer-events: none -->
    <iframe
      frameborder="0"
      scrolling="no"
      style="pointer-events: none; left: 0px; top: 0px; width: 100%; height: 100%; position: absolute; z-index: -1; background-color: transparent;"
      allowtransparency="true"
    />
    <div class="dialog-content" :style="style2">
      <!-- 是否添加resizable支持 -->
      <!-- relative=true, 表示resize组件的left、top始终为0 -->
      <!-- 由css布局决定, 因为resize组件是dialog-content的子组件,跟随父容器变化! -->
      <v-resizable
        v-if="resizable"
        :relative="true"
        :width="width"
        :height="height"
        @resize:move="onResizeMove"
      >
        <div class="dialog-header">
          <slot name="header" />
          <button type="button" class="el-dialog__headerbtn" @click="onClose">
            <i class="el-dialog__close el-icon el-icon-close" />
          </button>
        </div>
        <div class="dialog-body">
          <!-- <el-scrollbar style="height:100%;"> -->
          <slot name="body" />
          <!-- </el-scrollbar> -->
        </div>
        <div class="dialog-footer">
          <slot name="footer" />
        </div>
      </v-resizable>
      <template v-else>
        <div class="dialog-header">
          <slot name="header" />
          <button type="button" class="el-dialog__headerbtn" @click="onClose">
            <i class="el-dialog__close el-icon el-icon-close" />
          </button>
        </div>
        <div class="dialog-body">
          <!-- <el-scrollbar style="height:100%;"> -->
          <slot name="body" />
          <!-- </el-scrollbar> -->
        </div>
        <div class="dialog-footer">
          <slot name="footer" />
        </div>
      </template>
    </div>
  </div>
</template>

<script>
import DragDialog from '@/directive/drag-dialog'
import Resizable from '@/components/Resizable'

function PxStr(x) {
  if (typeof x === 'number') return x + 'px'
  else return x
}

export default {
  components: { 'v-resizable': Resizable },
  directives: { DragDialog },
  props: {
    width: {
      type: Number,
      required: false,
      default: 400
    },
    height: {
      type: Number,
      required: false,
      default: 300
    },
    top: {
      type: String,
      required: false,
      default: '16vh'
    },
    modal: {
      type: Boolean,
      required: false,
      default: true
    },
    // 是否增加drag支持
    draggable: {
      type: Boolean,
      required: false,
      default: true
    },
    resizable: {
      type: Boolean,
      required: false,
      default: true
    }
  },
  data() {
    return {
      zIndex: 0,
      // 对话框原始位置
      originLeft: 0,
      originTop: 0,

      // 对话框当前位置
      currentLeft: '50%', // 默认水平居中
      currentMarginLeft: 0,
      currentTop: this.top,

      // 对话框尺寸
      eWidth: 0,
      eHeight: 0
    }
  },
  computed: {
    style1() {
      if (this.modal) {
        return {
          zIndex: this.zIndex,
          // 全屏遮罩
          margin: 0,
          top: 0,
          right: 0,
          bottom: 0,
          left: 0
        }
      } else {
        return {
          zIndex: this.zIndex,
          left: PxStr(this.currentLeft),
          top: PxStr(this.currentTop),
          marginLeft: PxStr(this.currentMarginLeft),
          // 遮罩宽和高(此时遮罩和对话框大小一致)
          width: PxStr(this.eWidth),
          height: PxStr(this.eHeight)
        }
      }
    },
    style2() {
      if (this.modal) {
        return {
          left: PxStr(this.currentLeft),
          top: PxStr(this.currentTop),
          marginLeft: PxStr(this.currentMarginLeft),
          // 对话框宽和高
          width: PxStr(this.eWidth),
          height: PxStr(this.eHeight)
        }
      } else {
        return {
          left: 0,
          right: 0,
          // 对话框宽和高
          width: PxStr(this.eWidth),
          height: PxStr(this.eHeight)
        }
      }
    }
  },
  created() {
    this.eWidth = this.width
    this.eHeight = this.height
    this.currentMarginLeft = -1 * this.eWidth * 0.5
  },
  mounted() {
    this.zIndex = this.getMaxZIndex()
    // 获取px值
    let rect = null
    if (this.modal) {
      // 模态对话框针对div.dialog-content进行操作
      const el = this.$refs.dialog.querySelector('div.dialog-content')
      rect = el.getBoundingClientRect()
    } else {
      // 非模态对话框针对div.dialog-mask进行操作
      const el = this.$refs.dialog
      rect = el.getBoundingClientRect()
    }
    // 修正left值
    // 由于margin-left的存在,left值实际要小,需要把margin-left加回来!!!
    this.currentLeft = rect.left
    this.currentTop = rect.top
    // left值已经修正,不再需要margin-left了!
    this.currentMarginLeft = 0

    this.originLeft = this.currentLeft
    this.originTop = this.currentTop
  },
  methods: {
    getMaxZIndex() {
      return [...document.all].reduce(
        (r, e) => Math.max(r, +window.getComputedStyle(e).zIndex || 0),
        0
      )
    },
    onClose() {
      this.$emit('close')
    },
    onDrag(e) {
      // console.log('modal dialog:', e)
      // 向父组件发送drag消息
      this.$emit('drag', e)
    },
    onResizeMove(e) {
      // console.log('拖拽move:', e.width, e.left, '当前宽度:', this.eWidth)

      // 同步调整父组件(div.dialog-content)的left和top
      this.currentLeft = this.originLeft + e.left
      this.currentTop = this.originTop + e.top

      // 同步调整resize组件及父组件(div.dialog-content)的width和height
      this.eWidth = e.width
      this.eHeight = e.height
    }
  }
}
</script>

<style lang="scss">
@import './dialog.scss';
.dialog-content {
  .resizable-component {
    // 禁止滚动
    // overflow: hidden;
    // position: absolute !important;
    display: flex;
    flex-direction: column;
  }
}
</style>
